Análise da influência das bases de dados nas queries expandidas pelo AQE¶

Nesta análise, vamos identificar a influência das bases de dados nas expansões realizadas pelo AQE, além de quais os pesos mais adequados para os fatores de boosting de consulta ao elasticsearch.

Nesta análise vamos utilizar as queries da base REGIS para medir a performance do ranking, como também as 12 bases de dados utilizadas na expansão da consulta do AQE:

  • 01_DicionarioPetroleo_Curado_ComSinonimos
  • 02_Tesauro_comTraducoesRegis
  • 03_ListaCurada
  • 05_InstanciasBDIEP_Ativo_Bloco_Campo
  • 06_Termos_TabelaPocosANP2019
  • 07_Pocos_TabelaPocosANP2019
  • 08_Pocos_BDIEP_com2ou3_Siglas
  • 09_Glossario_ANP
  • 10_List_of_abbreviations_curada
  • 11_Lista_Feita_a_Mao
  • 12_Partex_Acronymis_Oil_Gas
  • 13_Lista_MWE

Carregando libs¶

In [1]:
import json
from pathlib import Path
import yaml
import pandas as pd
import numpy as np
import plotly.express as px

from utils.utils import adjust_new_expanded_queries, create_metrics, create_new_metrics,\
    create_validation_dataset, get_databases_queries, create_new_validation_dataset, \
    get_expanded_queries, make_elasticsearch_queries, make_elasticsearch_new_queries

Carregando as configurações e bases dados¶

In [2]:
with open("../conf/config.yaml", "r") as yamlfile:
    cfg = yaml.safe_load(yamlfile)
In [3]:
data_path = Path("../../dados/vocabulario_oil_gas")
databases = dict()
In [4]:
with open(data_path.joinpath("01_DicionarioPetroleo_Curado_ComSinonimos.csv"), "r", encoding='unicode_escape') as f:
    databases["01_DicionarioPetroleo_Curado_ComSinonimos"] = f.read().replace(";", "\n").split("\n")
    databases["01_DicionarioPetroleo_Curado_ComSinonimos"] = [e.strip().lower() for e in databases["01_DicionarioPetroleo_Curado_ComSinonimos"]]
print(databases["01_DicionarioPetroleo_Curado_ComSinonimos"][:20])
['2d seismic', 'sísmica 2d', '3d seismic', 'sísmica 3d', '4c seismic survey', 'levantamento sísmico 4c', '4d seismic', 'sísmica 4d', 'a horizon of soil', 'horizonte a de solo', 'a layer', 'camada a', 'a5s adapter', 'adaptador a5s', 'aalenian', 'aaleniano', 'a-b electrode', 'eletrodo a-b', 'abandoned meander', 'meandro abandonado']
In [5]:
with open(data_path.joinpath("02_Tesauro_comTraducoesRegis.csv"), "r", encoding='unicode_escape') as f:
    databases["02_Tesauro_comTraducoesRegis"] = f.read().replace("#", ";").replace("\t", "").replace(";", "\n").split("\n")
    databases["02_Tesauro_comTraducoesRegis"] = [e.strip().lower() for e in databases["02_Tesauro_comTraducoesRegis"] if e != ""]
print(databases["02_Tesauro_comTraducoesRegis"][:20])
['2 1/2 dimensional model', 'shape', 'forma', 'two and one half dim model', 'dimensional model', 'modelo dimensional', '2 1/2 dimensional', 'geophysical model', 'modelo geofísico', 'three dimensional', 'tridimensional', 'two dimensional', 'mathematics', 'matemática', 'empirical analysis', 'análise empírica', 'probability', 'probabilidade', 'well', 'poço']
In [6]:
with open(data_path.joinpath("03_ListaCurada.csv"), "r", encoding='unicode_escape') as f:
    databases["03_ListaCurada"] = f.read().split("\n")
    databases["03_ListaCurada"] = [e.strip().lower() for e in databases["03_ListaCurada"] if e != ""]
print(databases["03_ListaCurada"][:20])
['abandonado', 'abandonados', 'abandono', 'abastecedor', 'abastecimento', 'abatimento', 'abertas', 'aberto', 'abertos', 'abertura', 'abissais', 'abissal', 'ablação', 'abordados', 'abordagem', 'abrangência', 'abrangidos', 'abrasão', 'abrigo', 'abrir']
In [7]:
with open(data_path.joinpath("05_InstanciasBDIEP_Ativo_Bloco_Campo.csv"), "r", encoding='unicode_escape') as f:
    databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"] = f.read().replace(";", "\n").split("\n")
    databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"] = [e.strip().lower() for e in databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"] if e != ""]
print(databases["05_InstanciasBDIEP_Ativo_Bloco_Campo"][:20])
['uo-bc/atp-s', 'ativo de producao sul', 'uo-es/atp-ab', 'ativo de producao albacora', 'agp/aa', 'america do norte e africa', 'e&p-inter/aa', 'america do norte e africa', 'uo-es/atp-ro', 'ativo de producao roncador', 'uo-rio/atp-mero', 'ativo de producao de mero', 'libra/gcpp', 'gestao do contrato de partilha da producao', 'uo-am/atp-u', 'ativo de producao urucu', 'uo-ba/atp-bm', 'ativo de producao bahia mar', 'uo-ba/atp-n', 'ativo de producao norte']
In [8]:
with open(data_path.joinpath("06_Termos_TabelaPocosANP2019.csv"), "r", encoding='unicode_escape') as f:
    databases["06_Termos_TabelaPocosANP2019"] = f.read().replace(";", "\n").split("\n")
    databases["06_Termos_TabelaPocosANP2019"] = [e.strip().lower() for e in databases["06_Termos_TabelaPocosANP2019"] if e != ""]
print(databases["06_Termos_TabelaPocosANP2019"][:20])
['ns-07', 'aban abraham', 'sonda ns-07', 'sonda aban abraham', 'ss-39', 'alaskan star', 'sonda ss-39', 'sonda alaskan star', 'ss-83', 'alpha star', 'sonda ss-83', 'sonda alpha star', 'alt-107', 'alt-107', 'sonda alt-107', 'sonda alt-107', 'ns-43', 'amaralina star', 'sonda ns-43', 'sonda amaralina star']
In [9]:
with open(data_path.joinpath("07_Pocos_TabelaPocosANP2019.csv"), "r", encoding='unicode_escape') as f:
    databases["07_Pocos_TabelaPocosANP2019"] = f.read().replace(";", "\n").split("\n")
    databases["07_Pocos_TabelaPocosANP2019"] = [e.strip().lower() for e in databases["07_Pocos_TabelaPocosANP2019"] if e != ""]
print(databases["07_Pocos_TabelaPocosANP2019"][:20])
['7-mg-450-ba', '7mg  0450  ba', '3-ftd-5-al', '3ftd 0005  al', '3-pml-5-rn', '3pml 0005  rn', '1-rm-2-rn', '1rm  0002  rn', '4-rjs-419d-rjs', '4rjs 0419d rj', '3-ga-20d-ses', '3ga  0020d ses', '3-re-24-rn', '3re  0024  rn', '3-rjs-179-rj', '3rjs 0179  rj', '1-ses-66-se', '1ses 0066  se', '4-rr-5-al', '4rr  0005  al']
In [10]:
with open(data_path.joinpath("08_Pocos_BDIEP_com2ou3_Siglas.csv"), "r", encoding='utf-8-sig') as f:
    databases["08_Pocos_BDIEP_com2ou3_Siglas"] = f.read().replace(";", "\n").split("\n")
    databases["08_Pocos_BDIEP_com2ou3_Siglas"] = [e.strip().lower() for e in databases["08_Pocos_BDIEP_com2ou3_Siglas"] if e != ""]
print(databases["08_Pocos_BDIEP_com2ou3_Siglas"][:20])
['1-apl-4dpa-rjs', '1-apl-4xa-rjs', '1apl 0004xarjs', '1-bg-2dpa-sps', '1-bg-2xa-sps', '1bg  0002xasps', '1-bg-2dpb-sps', '1-bg-2xb-sps', '1bg  0002xbsps', '3-cps-7hpa-es', '3-cps-7wa-es', '3cps 0007waes', '3-ess-110hpa', '3-ess-110wa', '3ess 0110waes', '3-luc-81dpa-am', '3-luc-81xa-am', '3luc 0081xaam', '3-nfa-7hpa-es', '3-nfa-7wa-es']
In [11]:
with open(data_path.joinpath("09_Glossario_ANP.csv"), "r", encoding='unicode_escape') as f:
    databases["09_Glossario_ANP"] = f.read().replace(";", "\n").split("\n")
    databases["09_Glossario_ANP"] = [e.strip().lower() for e in databases["09_Glossario_ANP"] if e != ""]
print(databases["09_Glossario_ANP"][:20])
['abandono de campo', 'abandono de poço', 'abastecimento nacional de combustíveis', 'ação corretiva', 'ação preventiva', 'acidente', 'acondicionamento de gás natural', 'acordo de cessão de capacidade', 'acordo de individualização da produção', 'acordo de interconexão , contrato de interconexão', 'acreditação', 'acumulação', 'adequação ao uso', 'adimplente', 'aditivo', 'aditivo em frasco para óleo lubrificante', 'aditivo para combustíveis automotivos', 'aditivo para óleo lubrificante acabado', 'administração aeroportuária local', 'administrado']
In [12]:
with open(data_path.joinpath("10_List_of_abbreviations_curada.csv"), "r", encoding='unicode_escape') as f:
    databases["10_List_of_abbreviations_curada"] = f.read().replace(";", "\n").split("\n")
    databases["10_List_of_abbreviations_curada"] = [e.strip().lower() for e in databases["10_List_of_abbreviations_curada"] if e != ""]
print(databases["10_List_of_abbreviations_curada"][:20])
['aav', 'annulus access valve', 'aban', 'abnd', 'abandonment', 'acc', 'air-cooled heat condenser', 'ache', 'air-cooled heat exchanger', 'acou', 'acoustic', 'acqu', 'acquisition log', 'ade', 'advanced decision making environment', 'adep', 'awaiting development with exploration potential', 'adroc', 'advanced rock properties report', 'adt']
In [13]:
with open(data_path.joinpath("11_Lista_Feita_a_Mao.csv"), "r", encoding='unicode_escape') as f:
    databases["11_Lista_Feita_a_Mao"] = f.read().replace(",", ";").replace(";", "\n").split("\n")
    databases["11_Lista_Feita_a_Mao"] = [e.strip().lower() for e in databases["11_Lista_Feita_a_Mao"] if e != ""]
print(databases["11_Lista_Feita_a_Mao"][:20])
['gmdss', 'global maritime distress and safety system', 'perfil rmn', 'perfil de ressonância magnética nuclear', 'tfr', 'teste de formação a poço revestido', 'pig', 'pipeline intervention gadget', 'e&p', 'exploração e produção', 'petrobras logística de exploração e produção s.a.', 'pb-log', 'rx', 'raios x', 'raio x', 'raio-x', 'copper nickel', 'cuni', 'cu-ni', 'cobre níquel']
In [14]:
with open(data_path.joinpath("12_Partex_Acronymis_Oil_Gas.csv"), "r") as f:
    databases["12_Partex_Acronymis_Oil_Gas"] = f.read().replace(";", "\n").split("\n")
    databases["12_Partex_Acronymis_Oil_Gas"] = [e.strip().lower() for e in databases["12_Partex_Acronymis_Oil_Gas"] if e != ""]
print(databases["12_Partex_Acronymis_Oil_Gas"][:20])
['bb', 'bid bond', 'bep', 'break even point', 'bom', 'bill of materials', 'br', 'budget requisition', 'capex', 'capital expenditure', 'cft', 'call for tender', 'ci', 'capital intensity', 'db', 'declining balance', 'dcc', 'decision cycle compression', 'ddb', 'double declining balance']
In [15]:
with open(data_path.joinpath("13_Lista_MWE.txt"), "r") as f:
    databases["13_Lista_MWE"] = f.read().replace(",", "\n").split("\n")
    databases["13_Lista_MWE"] = [e.strip().lower() for e in databases["13_Lista_MWE"] if e != ""]
print(databases["13_Lista_MWE"][:20])
['1a 0001 ba', '1aa 0001 rn', '1ab 0001 ba', '1ab 0001 pa', '1ab 0001 se', '1ab 0001 sp', '1ab 0001a se', '1ab 0002 se', '1abc 0001 es', '1abr 0001 es', '1abv 0001d rn', '1abv 0002d rn', '1ac 0001 pa', '1ad 0001 am', '1ad 0001a am', '1ae 0001 rn', '1af 0001 pa', '1ag 0001 ba', '1ag 0001 se', '1ag 0005 se']

Expansão das queries¶

Agora vamos coletar as expansões das queries da base REGIS.

In [16]:
with open("../../dados/regis/regis_queries.json", 'r') as regis_file:
    regis_queries = json.load(regis_file)
In [17]:
regis_queries = get_expanded_queries(regis_queries)
regis_queries[:5]
Out[17]:
[{'title': 'História da geoquímica na Petrobras',
  'query_id': 'Q1',
  'expanded_query': '((História da geoquímica na Petrobras) OR ( (historia^1.000 OR história^0.890 OR history^0.571 OR "histórico do campo"^0.525 OR review^0.159 OR revisão^0.164 OR "histórico de caso"^0.225) OR (geoquimica^1.000 OR geoquímica^0.890 OR geoquímicas^0.691 OR geoquímico^0.672 OR geoquimicos^0.736 OR geoquimicas^0.691 OR geoquimico^0.672 OR geochemistry^0.601 OR "geochemical anomaly"^0.225 OR "geochemical interpretation"^0.225 OR "composição dos sedimentos"^0.225 OR "sediment composition"^0.225 OR geology^0.195 OR geologia^0.253 OR petrochemistry^0.153 OR petroquímica^0.184 OR "geochemical cycle"^0.225 OR petrografia^0.255 OR petrography^0.191 OR "análise de rochas"^0.225 OR "rock analysis"^0.225 OR "composição das rochas"^0.225 OR "rock composition"^0.225 OR transect^0.150 OR "geochemical map"^0.225 OR "geochemical exploration"^0.225 OR "geochemical logging"^0.225 OR geophysics^0.179 OR geofísica^0.256 OR "geochemical data"^0.225) OR petrobras^1.000 ))'},
 {'title': 'Lógica fuzzy aplicada  à industria do petróleo',
  'query_id': 'Q2',
  'expanded_query': '((Lógica fuzzy aplicada à industria do petróleo) OR ( ("logica fuzzy"^1.000 OR "lógica fuzzy"^0.667 OR "lógica difusa"^0.667 OR "logica nebulosa"^0.667 OR "logica difusa"^0.667 OR "fuzzy logic"^0.667) OR ("industria do petroleo"^1.000 OR "indústria do petróleo"^0.667 OR "industria de petroleo"^0.667 OR "petroleum industry"^0.667) OR (logica^1.000 OR lógica^0.890 OR lógico^0.744) OR fuzzy^1.000 OR (aplicada^1.000 OR aplicado^0.795 OR aplicados^0.756) OR (industria^1.000 OR indústria^0.890 OR industry^0.576) OR (petroleo^1.000 OR petróleo^0.890 OR petróleos^0.705 OR petroleos^0.705 OR petroleum^0.632 OR "gasolina natural"^0.525 OR "natural gas"^0.350 OR "gás natural"^0.423 OR "commingled production"^0.525 OR "produção misturada"^0.525 OR "óleo cru"^0.525 OR "crude oil"^0.353 OR "hydrocarbon potential"^0.225 OR "potencial de hidrocarbonetos"^0.225 OR "fluido do reservatório"^0.225 OR "reservoir fluid"^0.225 OR "raw material"^0.225 OR "matéria prima"^0.224 OR "razão de hidrocarbonetos"^0.225 OR "hydrocarbon ratio"^0.225 OR "fossil fuel"^0.150 OR "combustível fóssil"^0.225) ))'},
 {'title': 'Simulação de reservatórios usando linhas de fluxo',
  'query_id': 'Q3',
  'expanded_query': '((Simulação de reservatórios usando linhas de fluxo) OR ( (simulacao^1.000 OR simulação^0.890 OR simulações^0.777 OR simulacoes^0.777 OR simulation^0.589 OR flowtran^0.525 OR "virtual reality"^0.525 OR analogy^0.150 OR analogia^0.205 OR "testemunho artificial"^0.225 OR "artificial core"^0.225 OR model^0.181 OR modelo^0.218 OR tomografia^0.207 OR tomography^0.156 OR "history matching"^0.225 OR streamline^0.163 OR "projeto assistido por computador"^0.225 OR "computer assisted design"^0.225 OR "método de galerkin"^0.225 OR "galerkin method"^0.225) OR (reservatorios^1.000 OR reservatórios^0.890 OR reservatório^0.781 OR reservatorio^0.781 OR reservoir^0.577 OR aqüífero^0.556 OR aquifer^0.406 OR "porous media"^0.225 OR "membrana porosa"^0.225 OR "área provada"^0.225 OR "proved area"^0.225 OR "zona múltipla"^0.225 OR multizone^0.150 OR "noncommercial pool"^0.225 OR "acumulação não-comercial"^0.225 OR formation^0.167 OR formação^0.198 OR "petroleum system"^0.225 OR multizona^0.150) OR usando^1.000 OR (linhas^1.000 OR linha^0.694 OR line^0.555 OR streamline^0.360 OR geometria^0.185 OR geometry^0.150 OR paralelo^0.205 OR parallel^0.178 OR perpendicular^0.200) OR (fluxo^1.000 OR fluxos^0.724 OR flux^0.597) ))'},
 {'title': 'Detecção de exsudações de óleo nas bacias de Sergipe-Alagoas',
  'query_id': 'Q4',
  'expanded_query': '((Detecção de exsudações de óleo nas bacias de Sergipe-Alagoas) OR ( (deteccao^1.000 OR detecção^0.890 OR detection^0.694 OR identification^0.194 OR identificação^0.251 OR camouflage^0.150 OR camuflagem^0.216 OR measuring^0.184 OR medição^0.249 OR "project payette"^0.225 OR "projeto payette"^0.225 OR detector^0.228 OR visualization^0.173 OR visualização^0.234 OR locating^0.163 OR localização^0.211) OR (exsudacoes^1.000 OR exsudações^0.890 OR exsudação^0.684 OR exsudacao^0.684 OR seep^0.591 OR seepage^0.604 OR seeps^0.680 OR contamination^0.193 OR contaminação^0.215 OR "soil pollution"^0.225 OR "poluição do solo"^0.225 OR "oil waste"^0.225 OR "rejeito de óleo"^0.225 OR drenagem^0.171 OR drainage^0.168 OR "water pollution"^0.225 OR "poluição da água"^0.225 OR leak^0.173 OR vazamento^0.193 OR "trickle flow"^0.225 OR "fluxo em gotas"^0.225 OR "environmental pollution"^0.225) OR (oleo^1.000 OR óleo^0.890 OR óleos^0.723 OR oleos^0.723 OR oil^0.591) OR (bacias^1.000 OR bacia^0.786 OR basin^0.664 OR "hinge line"^0.363 OR "linha de charneira"^0.525 OR enseada^0.189 OR embayment^0.163 OR "geologia estrutural"^0.225 OR "structural geology"^0.225 OR baía^0.201 OR bay^0.161 OR "brackish environment"^0.225 OR "ambiente salobro"^0.225) OR sergipe-alagoas^1.000 ))'},
 {'title': 'Permeabilidade em Marlim',
  'query_id': 'Q5',
  'expanded_query': '((Permeabilidade em Marlim) OR ( (permeabilidade^1.000 OR permeabilidades^0.762 OR permeability^0.634 OR permeation^0.156 OR permeação^0.214 OR "dano de formação"^0.225 OR "formation damage"^0.225 OR "klinkenberg effect"^0.225 OR "efeito klinkenberg"^0.225 OR "controle de perfil"^0.225 OR "profile control"^0.225 OR "capacidade de vazão"^0.225 OR "flow capacity"^0.225 OR tortuosity^0.162 OR tortuosidade^0.248 OR "análise de crescimento da pressão"^0.225 OR "pressure buildup analysis"^0.225 OR porosity^0.207 OR porosidade^0.282 OR "nuclear magnetic logging"^0.225 OR "perfilagem nuclear magnética"^0.225 OR "rock property"^0.225 OR "propriedades das rochas"^0.225 OR "sediment texture"^0.225 OR "textura dos sedimentos"^0.225 OR "kozeny carmen equation"^0.225 OR "equação de kozeny carmen"^0.225 OR "efeito de película"^0.225 OR "skin effect"^0.225 OR "core analysis"^0.225 OR "análise de testemunhos"^0.225 OR "suscetibilidade a injeção de água"^0.225 OR "waterflood susceptibility"^0.225 OR permeameter^0.150 OR permeâmetro^0.188) OR (marlim^1.000 OR mrl^0.583) ))'}]

Criando queries para cada base de dados¶

Agora, para cada base de dados, vamos identificar se cada termo expandido está presente ou não naquela base de dados, zerando o fator de boosting quando não estiver. Para os fatores de boosting vamos experimentar entre 0,1 e 1,5, com intervalos de 0,1. Esse fator multiplicará o valor original de boost do AQE.

In [18]:
databases_queries = get_databases_queries(databases, regis_queries, np.arange(0.1, 1.6, 0.1))

Realizando consultas no Elasticsearch¶

Em posse das queries para cada fator e base de dados, agora vamos realizar as consultas ao elastic search e criar o dataset de validação, o qual possui informações do ground truth da base de dados REGIS.

In [19]:
ranking_result_df = make_elasticsearch_queries(databases_queries, cfg, 50)
Started querying database 01_DicionarioPetroleo_Curado_ComSinonimos
Started querying database 02_Tesauro_comTraducoesRegis
Started querying database 03_ListaCurada
Started querying database 05_InstanciasBDIEP_Ativo_Bloco_Campo
Started querying database 06_Termos_TabelaPocosANP2019
Started querying database 07_Pocos_TabelaPocosANP2019
Started querying database 08_Pocos_BDIEP_com2ou3_Siglas
Started querying database 09_Glossario_ANP
Started querying database 10_List_of_abbreviations_curada
Started querying database 11_Lista_Feita_a_Mao
Started querying database 12_Partex_Acronymis_Oil_Gas
Started querying database 13_Lista_MWE
In [20]:
ranking_result_df.head()
Out[20]:
database_name query_id factor document_id relevance
0 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BG.03964 9.573541
1 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BG.03967 9.460924
2 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BG.04004 9.276192
3 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-TU.20287 9.119863
4 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BT.05005 9.103277
In [21]:
ground_truth = pd.read_csv("../../dados/regis/regis_ground_truth.csv")
ground_truth.head()
Out[21]:
query_id document_id relevance
0 Q1 BR-BG.03944 1
1 Q1 BR-BG.03925 1
2 Q1 BR-TU.23384 0
3 Q1 BR-TU.12209 0
4 Q1 BR-BG.04089 2
In [22]:
validation_dataset = create_validation_dataset(ranking_result_df, ground_truth)
validation_dataset.head()
Out[22]:
database_name query_id factor document_id relevance_ranking relevance_ground_truth evaluated
0 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BG.03964 9.573541 2.0 True
1 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BG.03967 9.460924 3.0 True
2 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BG.04004 9.276192 1.0 True
3 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-TU.20287 9.119863 0.0 True
4 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 BR-BT.05005 9.103277 1.0 True
In [23]:
validation_dataset.to_csv("../data/databases_es_documents.csv", index=False)
In [24]:
# validation_dataset = pd.read_csv("../data/databases_es_documents.csv")
# validation_dataset.head()

Análise das consultas no Elasticsearch¶

Agora vamos criar as métricas para cada base de dados e fator e visualizar os resultados.

Criando métricas¶

In [25]:
metrics_df = create_metrics(validation_dataset)
metrics_df.head()
Out[25]:
database_name query_id factor ndcg ap eval_prop
0 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.1 0.723207 0.295181 0.815789
1 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.2 0.723207 0.295181 0.815789
2 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.3 0.723207 0.295181 0.815789
3 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.4 0.723207 0.295181 0.815789
4 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.5 0.723207 0.295181 0.815789
In [26]:
metrics_df.to_csv("../data/databases_metrics.csv", index=False)

Avaliando métricas¶

Vamos agora avaliar as métricas. Vamos utilizar as seguintes métricas:

  • ndcg - Normalized Discounted Cumulative Gain
  • map - Mean Average Precision
  • eval_prop - Proporção de documentos avaliados
In [27]:
# metrics_df = pd.read_csv("../data/databases_metrics.csv")
# metrics_df.head()
In [28]:
data_viz = metrics_df.groupby(
    ["database_name", "factor"]
).agg(
    "mean"
).reset_index(
)

data_viz.head()
Out[28]:
database_name factor ndcg ap eval_prop
0 01_DicionarioPetroleo_Curado_ComSinonimos 0.1 0.730155 0.442177 0.671224
1 01_DicionarioPetroleo_Curado_ComSinonimos 0.2 0.729710 0.445689 0.653300
2 01_DicionarioPetroleo_Curado_ComSinonimos 0.3 0.723692 0.434536 0.638949
3 01_DicionarioPetroleo_Curado_ComSinonimos 0.4 0.715381 0.420195 0.626818
4 01_DicionarioPetroleo_Curado_ComSinonimos 0.5 0.708339 0.419058 0.610318
In [29]:
fig = px.line(
    data_viz,
    x="factor",
    y="ndcg",
    color="database_name",
    markers=True,
    title="Performances das bases de dados com diferentes fatores"
).add_hline(
    y=0.7351,
    line_dash="dash",
    line_color="black"
)
fig.show()

É possível ver que todas as bases de dados, a partir de um fator de 0,2 existe uma tendência decrescente do NDCG ao passo que aumenta o fator de multiplicação do boosting.

Identificando melhor fator de multipliação do boost para cada base de dados¶

Vamos repetir o processo acima, mas agora com objetivo de identificar qual o melhor fator de multiplicação do boost para cada base de dados, utilizando fatores entre 0 e 0,2.

In [30]:
databases_queries = get_databases_queries(databases, regis_queries, np.arange(0.01, 0.25, 0.01))
In [31]:
ranking_result_df = make_elasticsearch_queries(databases_queries, cfg, 50)
Started querying database 01_DicionarioPetroleo_Curado_ComSinonimos
Started querying database 02_Tesauro_comTraducoesRegis
Started querying database 03_ListaCurada
Started querying database 05_InstanciasBDIEP_Ativo_Bloco_Campo
Started querying database 06_Termos_TabelaPocosANP2019
Started querying database 07_Pocos_TabelaPocosANP2019
Started querying database 08_Pocos_BDIEP_com2ou3_Siglas
Started querying database 09_Glossario_ANP
Started querying database 10_List_of_abbreviations_curada
Started querying database 11_Lista_Feita_a_Mao
Started querying database 12_Partex_Acronymis_Oil_Gas
Started querying database 13_Lista_MWE
In [32]:
validation_dataset = create_validation_dataset(ranking_result_df, ground_truth)
In [33]:
metrics_df = create_metrics(validation_dataset)
metrics_df.head()
Out[33]:
database_name query_id factor ndcg ap eval_prop
0 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.01 0.723207 0.295181 0.815789
1 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.02 0.723207 0.295181 0.815789
2 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.03 0.723207 0.295181 0.815789
3 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.04 0.723207 0.295181 0.815789
4 01_DicionarioPetroleo_Curado_ComSinonimos Q1 0.05 0.723207 0.295181 0.815789
In [34]:
data_viz = metrics_df.groupby(
    ["database_name", "factor"]
).agg(
    "mean"
).reset_index(
)

fig = px.line(
    data_viz,
    x="factor",
    y="ndcg",
    color="database_name",
    markers=True,
    title="Performances das bases de dados com diferentes fatores"
).add_hline(
    y=0.7351,
    line_dash="dash",
    line_color="black"
)
fig.show()

Podemos identificar que os seguintes fatores são os melhores para cada base:

  • 01_DicionarioPetroleo_Curado_ComSinonimos: 0.03
  • 02_Tesauro_comTraducoesRegis: 0.11
  • 03_ListaCurada: 0.0
  • 05_InstanciasBDIEP_Ativo_Bloco_Campo: 0.01
  • 06_Termos_TabelaPocosANP2019: 0.1
  • 07_Pocos_TabelaPocosANP2019: 0.0
  • 08_Pocos_BDIEP_com2ou3_Siglas: 0.0
  • 09_Glossario_ANP: 0.14
  • 10_List_of_abbreviations_curada: 0.13
  • 11_Lista_Feita_a_Mao: 0.0
  • 12_Partex_Acronymis_Oil_Gas: 0.12
  • 13_Lista_MWE: 0.08

Vejamos o impacto de cada base de dados no ndcg:

In [35]:
data_viz.groupby("database_name").agg({"ndcg": "max"}).reset_index().sort_values("ndcg", ascending=False)
Out[35]:
database_name ndcg
4 06_Termos_TabelaPocosANP2019 0.759765
11 13_Lista_MWE 0.744528
1 02_Tesauro_comTraducoesRegis 0.741415
7 09_Glossario_ANP 0.739109
10 12_Partex_Acronymis_Oil_Gas 0.737709
0 01_DicionarioPetroleo_Curado_ComSinonimos 0.737612
8 10_List_of_abbreviations_curada 0.736354
3 05_InstanciasBDIEP_Ativo_Bloco_Campo 0.735321
5 07_Pocos_TabelaPocosANP2019 0.735069
6 08_Pocos_BDIEP_com2ou3_Siglas 0.735069
9 11_Lista_Feita_a_Mao 0.735069
2 03_ListaCurada 0.734307

Criando novas queries baseados nos fatores encontrados¶

Agora vamos ajustar as queries para utilizar os melhores fatores para cada base de dados.

In [36]:
databases_factors = {
    "01_DicionarioPetroleo_Curado_ComSinonimos": 0.03,
    "02_Tesauro_comTraducoesRegis": 0.11,
    "03_ListaCurada": 0.0,
    "05_InstanciasBDIEP_Ativo_Bloco_Campo": 0.01,
    "06_Termos_TabelaPocosANP2019": 0.1,
    "07_Pocos_TabelaPocosANP2019": 0.0,
    "08_Pocos_BDIEP_com2ou3_Siglas": 0.0,
    "09_Glossario_ANP": 0.14,
    "10_List_of_abbreviations_curada": 0.13,
    "11_Lista_Feita_a_Mao": 0.0,
    "12_Partex_Acronymis_Oil_Gas": 0.12,
    "13_Lista_MWE": 0.08,
}
In [37]:
new_expanded_queries = adjust_new_expanded_queries(
    databases,
    regis_queries,
    databases_factors
)
In [38]:
ranking_result_df = make_elasticsearch_new_queries(new_expanded_queries, cfg, 50)
ranking_result_df.head()
Out[38]:
query_id document_id relevance
0 Q1 BR-BG.03964 10.551333
1 Q1 BR-BG.03967 10.368014
2 Q1 BR-BG.04004 10.334161
3 Q1 BR-TU.19978 10.031455
4 Q1 BR-BG.04149 9.952123
In [39]:
validation_dataset = create_new_validation_dataset(ranking_result_df, ground_truth)
validation_dataset.head()
Out[39]:
query_id document_id relevance_ranking relevance_ground_truth evaluated
0 Q1 BR-BG.03964 10.551333 2.0 True
1 Q1 BR-BG.03967 10.368014 3.0 True
2 Q1 BR-BG.04004 10.334161 1.0 True
3 Q1 BR-TU.19978 10.031455 0.0 True
4 Q1 BR-BG.04149 9.952123 1.0 True
In [40]:
metrics_df = create_new_metrics(validation_dataset)
metrics_df.head()
Out[40]:
query_id ndcg ap eval_prop
0 Q1 0.713180 0.290941 0.792208
1 Q10 0.951204 0.843068 0.705882
2 Q11 0.667498 0.450000 0.888889
3 Q12 0.763789 0.396627 0.661290
4 Q13 0.951078 0.840335 0.627451
In [41]:
metrics_df["ndcg"].mean()
Out[41]:
0.757097004197905

É possível observar que o NDCG médio aumentou 2,18% quando comparado com ao NDCG médio da consulta sem o AQE.

Conclusão¶

Foi possível identificar que algumas bases de dados são mais importantes que outras na expansão da consulta, onde algumas trazem resultados inferiores comparando sem o uso do AQE. As bases de dados mais importantes são:

  1. 06_Termos_TabelaPocosANP2019 com ndcg de 0.759765
  2. 13_Lista_MWE com ndcg de 0.751475
  3. 09_Glossario_ANP com ndcg de 0.739109
  4. 12_Partex_Acronymis_Oil_Gas com ndcg de 0.737709
  5. 01_DicionarioPetroleo_Curado_ComSinonimos com ndcg de 0.737612
  6. 10_List_of_abbreviations_curada com ndcg de 0.736354
  7. 05_InstanciasBDIEP_Ativo_Bloco_Campo com ndcg de 0.735321

Utilizando os melhores pesos para cada base de dados o NDCG ficou abaixo do NDCG utilizando apenas a base de dados 06_Termos_TabelaPocosANP2019, mas ficou acima das demais bases, atingindo um NDCG de 0.756874. Tendo em vista que utilizar sete bases traz uma maior variabilidade de documentos e atingiu um NDCG 0.00289 menor, concluímos que utilizar os fatores de boosting sugeridos traz o melhor resultado encontrado até então. Segue os fatores de boosting para cada base de dados:

  • 01_DicionarioPetroleo_Curado_ComSinonimos: 0.03
  • 02_Tesauro_comTraducoesRegis: 0.11
  • 03_ListaCurada: 0.0
  • 05_InstanciasBDIEP_Ativo_Bloco_Campo: 0.01
  • 06_Termos_TabelaPocosANP2019: 0.1
  • 07_Pocos_TabelaPocosANP2019: 0.0
  • 08_Pocos_BDIEP_com2ou3_Siglas: 0.0
  • 09_Glossario_ANP: 0.14
  • 10_List_of_abbreviations_curada: 0.13
  • 11_Lista_Feita_a_Mao: 0.0
  • 12_Partex_Acronymis_Oil_Gas: 0.12
  • 13_Lista_MWE: 0.08